package cn.lg.soar.common.util.jackson.annotations;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
 * 小数序列化
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD })
@JacksonAnnotationsInside
@JsonSerialize(using = DecimalSerialize.Serializer.class)
public @interface DecimalSerialize {

    /**
     * 格式：000.00，000.##，##.###，￥,###.00
     * @return
     */
    String value();

    RoundingMode mode() default RoundingMode.HALF_UP;

    String MONEY = ",##0.00";
    String MONEY_CN = "￥,##0.00";
    String MONEY_US = "$,##0.00";

    /**
     * 数值列化
     * @author luguoxiang
     * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
     */
    class Serializer extends JsonSerializer<Number> implements ContextualSerializer {

        private DecimalFormat format;

        public Serializer() {}

        public Serializer(DecimalSerialize annotation) {
            this.format = new java.text.DecimalFormat(annotation.value());
            this.format.setRoundingMode(annotation.mode());
        }

        @Override
        public void serialize(Number number, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(format.format(number));
        }

        @Override
        public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                                  final BeanProperty beanProperty) throws JsonMappingException {
            if (beanProperty != null) {
                DecimalSerialize annotation = beanProperty.getAnnotation(DecimalSerialize.class);
                if (annotation == null) {
                    annotation = beanProperty.getContextAnnotation(DecimalSerialize.class);
                }
                if (annotation != null) {
                    return new Serializer(annotation);
                }
                return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
            }
            return serializerProvider.findNullValueSerializer(null);
        }

    }
}
